<!--
 * @Author: yanjikun
 * @Date: 2022-03-22 11:27:15
 * @LastEditors: yanjikun
 * @LastEditTime: 2022-05-06 10:49:29
 * @Description: file content
-->
<template>
  <div :class="props.heightAdaptation ? 'table-wrapper' : ''">
    <Table
      ref="tableRef"
      v-bind="getBindValues"
      :data-source="tableData"
      @change="handleTableChange"
    >
      <template
        v-for="slotName in defaultSlots.filter((name) => Reflect?.has($slots, name))"
        #[slotName]="slotData"
        :key="slotName"
      >
        <slot :name="slotName" v-bind="slotData"></slot>
      </template>
      <!-- 个性化单元格 start -->
      <template
        v-for="slotName in ['bodyCell', 'headerCell']"
        #[slotName]="slotData"
        :key="slotName"
      >
        <slot :name="slotName" v-bind="slotData"></slot>
        <!-- 表格行操作start -->
        <template v-if="slotName === 'bodyCell' && getColumnKey(slotData.column) === '$action'">
          <TableAction :actions="slotData.column.actions(slotData)" />
        </template>
        <!-- 表格行操作end -->
        <template
          v-for="slotItem in getBindValues.columns?.filter((item) => item[slotName])"
          :key="getColumnKey(slotItem)"
        >
          <component
            :is="getComponent(slotItem?.[slotName]?.(slotData))"
            v-if="getColumnKey(slotData.column) === getColumnKey(slotItem)"
          ></component>
        </template>
      </template>
      <!-- 个性化单元格 end -->
    </Table>
  </div>
</template>

<script setup lang="ts">
  import { Table } from 'ant-design-vue'
  import { useSlots } from 'vue'
  import { useTableMethods } from './hooks/useTableMethods'
  import { useTableState } from './hooks/useTableState'
  import { defaultSlots, DynamicTableEmits, dynamicTableProps } from './dynamic-table'
  import { createTableContext } from './hooks/useTableContext'
  defineOptions({
    name: 'DynamicTable',
    inheritAttrs: false,
  })
  interface emitType extends DynamicTableEmits {}
  const props = defineProps(dynamicTableProps)
  const emit = defineEmits<emitType>()
  const slots = useSlots()
  const tableState = useTableState({ props, slots })
  const { tableData, getBindValues } = tableState
  const tableMethods = useTableMethods({ state: tableState, props, emit })
  const { handleTableChange, fetchData, getColumnKey, getComponent } = tableMethods
  const instance = {
    ...props,
    ...tableState,
    ...tableMethods,
  }
  createTableContext(instance)
  fetchData()
  defineExpose(instance)
</script>

<style scoped lang="less">
  .table-wrapper {
    height: 100%;

    :deep(.ant-table-wrapper),
    :deep(.ant-spin-nested-loading) {
      height: 100%;

      .ant-spin-container {
        height: 100%;
        display: flex;
        flex-direction: column;

        .ant-table {
          flex-grow: 1;
          height: 100%;

          .ant-table-container {
            height: 100%;
            display: flex;
            flex-direction: column;

            .ant-empty-normal {
              margin: 17px 0;
            }
          }

          .ant-table-container > div:last-child {
            flex-grow: 1;
            height: 0px;
          }
        }
      }
    }

    :deep(.ant-table-pagination) {
      text-align: right;
      margin: 10px 0;
    }
  }
</style>
